package cn.mazexal.examapi.services;

import cn.hutool.core.util.IdUtil;
import cn.mazexal.examapi.common.models.BizException;
import cn.mazexal.examapi.common.models.CustomerError;
import cn.mazexal.examapi.common.models.PagedData;
import cn.mazexal.examapi.common.models.PagedQuestionData;
import cn.mazexal.examapi.dataware.*;
import cn.mazexal.examapi.models.converter.*;
import cn.mazexal.examapi.models.db.*;
import cn.mazexal.examapi.models.enums.ExamStatus;
import cn.mazexal.examapi.models.enums.ExamTypeEnum;
import cn.mazexal.examapi.models.enums.QuestionTypeEnum;
import cn.mazexal.examapi.models.form.ReportQuestionForm;
import cn.mazexal.examapi.models.form.ReviewUserWrongQuestionForm;
import cn.mazexal.examapi.models.form.UserCollectForm;
import cn.mazexal.examapi.models.qry.ExamLogQry;
import cn.mazexal.examapi.models.qry.IDQry;
import cn.mazexal.examapi.models.qry.UserCollectQry;
import cn.mazexal.examapi.models.vo.*;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Mazexal
 * Date: 2025/5/11
 */
@Service
public class QuestionService {

    @Resource
    private ExamQuestionMapper examQuestionMapper;

    @Resource
    private ExamQuestionConverter examQuestionConverter;

    @Resource
    private QuestionTagMapper questionTagMapper;

    @Resource
    private TagMapper tagMapper;

    @Resource
    private TagConverter tagConverter;

    @Resource
    private CommonService commonService;
    @Resource
    private UserService userService;

    @Resource
    private UserCollectMapper userCollectMapper;

    @Resource
    private UserWrongMapper userWrongMapper;


    @Resource
    private UserWrongConverter userWrongConverter;

    @Resource
    private UserQuestionNoteMapper userQuestionNoteMapper;

    @Resource
    private ExamQuestionMaterialsMapper examQuestionMaterialsMapper;

    @Resource
    private ExamQuestionMaterialsConverter examQuestionMaterialsConverter;


    @Resource
    private UserExamLogMapper userExamLogMapper;

    @Resource
    private UserExamLogConverter userExamLogConverter;

    @Resource
    private ExamPageMapper examPageMapper;

    @Resource
    private ExamQuestionRelationshipMapper examQuestionRelationshipMapper;

    @Resource
    private UserQuestionFlagMapper userQuestionFlagMapper;

    @Resource
    private UserQuestionLogMapper userQuestionLogMapper;

    @Resource
    private ReportQuestionMapper reportQuestionMapper;

    /**
     * 添加收藏
     *
     * @return
     */
    public boolean manageUserCollect(UserCollectForm form) {
        ExamQuestionDO questionDO = examQuestionMapper.selectById(form.getQuestionId());
        if (questionDO == null) {
            throw new BizException(new CustomerError("500", "问题不存在"));
        }
        UserCollectDO userCollectDO = userCollectMapper.getExamQuestionById(form.getExamBankId(), form.getQuestionId(),
                form.getUserId());
        if (form.getCollect()) {
            if (userCollectDO != null) {
                userCollectDO.setIsDel(0);
                userCollectMapper.updateById(userCollectDO);
                return true;
            } else {
                CardMenuDO cardMenuDO = commonService.getCardMenuDOById(questionDO.getMenuId());
                Long topMenuId = commonService.getTopMenuIdByPath(cardMenuDO.getPath());
                userCollectDO = new UserCollectDO();
                userCollectDO.setId(IdUtil.getSnowflakeNextId());
                userCollectDO.setUserId(form.getUserId());
                userCollectDO.setExamBankId(form.getExamBankId());
                userCollectDO.setQuestionId(form.getQuestionId());
                userCollectDO.setCreateTime(System.currentTimeMillis());
                userCollectDO.setTopMenuId(topMenuId);
                userCollectDO.setMenuId(questionDO.getMenuId());
                return userCollectMapper.insert(userCollectDO) > 0;
            }
        } else {
            if (userCollectDO == null) {
                return false;
            }
            return userCollectMapper.deleteUserCollect(userCollectDO.getId()) > 0;
        }
    }

    /**
     * 删除收藏
     *
     * @return
     */
    public boolean removeUserCollect(IDQry qry) {
        return userCollectMapper.deleteUserCollect(qry.getId()) > 0;
    }


    public List<ExamQuestionVO> getExamQuestionListByIds(List<Long> questionIds, Long examBankId, Long userId) {
        List<ExamQuestionDO> examQuestionDOList = examQuestionMapper.selectByIds(questionIds);
        if (examQuestionDOList == null) {
            return new ArrayList<>();
        }
        return warpExamQuestionVoList(examQuestionDOList, examBankId, userId);
    }

    public ExamQuestionWithMaterialsVO getExamQuestionListByMenuIds(Long menuId, Long examBankId,
                                                                    Integer pageSize, Long userId,
                                                                    Integer questionType) {
        ExamQuestionWithMaterialsVO res = new ExamQuestionWithMaterialsVO();
        List<Long> subMenuIDs = commonService.getSubMenuIds(menuId, examBankId);
        UserQuestionFlagDO lastFlag = userQuestionFlagMapper.getUserLastFlag(userId, examBankId, menuId);
        Long limitTime = null;
        if (lastFlag != null) {
            limitTime = lastFlag.getCreateTime();
        }
        List<ExamQuestionDO> examQuestionDOList = examQuestionMapper.getExamQuestionListByMenuIds(subMenuIDs,
                examBankId, pageSize, limitTime, userId, questionType);
        if (CollectionUtils.isEmpty(examQuestionDOList)) {
            // 说明已近刷空题库,
            limitTime = System.currentTimeMillis();
            addUserQuestionFlagDO(examBankId, menuId, userId);
            // 插入标记以后重新获取一次
            examQuestionDOList = examQuestionMapper.getExamQuestionListByMenuIds(subMenuIDs,
                    examBankId, pageSize, limitTime, userId, questionType);
        }
        if (examQuestionDOList == null) {
            res.setQuestionList(Collections.EMPTY_LIST);
        }
        // 这里还要创建一个考试
        CardMenuDO menuDO = commonService.getMenuById(menuId);
        String title = menuDO.getName() + "专项训练";
        String remark = "用户" + userId + "专项训练";
        res.setUserExamId(addExamByQuestionList(examQuestionDOList, examBankId, userId, title, remark));
        res.setQuestionList(warpExamQuestionVoList(examQuestionDOList, examBankId, userId));
        return res;
    }


    public Long addExamByQuestionList(List<ExamQuestionDO> examQuestionDOList, Long examBankId, Long userId,
                                      String title, String remark) {
        if(CollectionUtils.isEmpty(examQuestionDOList)){
            throw new BizException(new CustomerError("500", "无题目可选"));
        }
        Long now = System.currentTimeMillis();
        int size = examQuestionDOList.size();
        Long examId = IdUtil.getSnowflakeNextId();
        ExamPageDO examPageDO = new ExamPageDO();
        examPageDO.setId(examId);
        examPageDO.setExamBankId(examBankId);
        examPageDO.setName(title);
        examPageDO.setExamType(ExamTypeEnum.PRACTISE_EXAM.getCode());
        examPageDO.setExamTime(Long.valueOf(size));
        examPageDO.setExamCreateTime(now);
        examPageDO.setCreateTime(now);
        examPageDO.setUpdateTime(now);
        examPageDO.setRemark(remark);
        examPageDO.setQuestionNum(size);
        if(size==0){
            examPageDO.setHardScore(BigDecimal.ZERO);
        }else{
            examPageDO.setHardScore(BigDecimal.valueOf(examQuestionDOList.stream().mapToDouble(item -> item.getHardScore().doubleValue()).sum()).divide(BigDecimal.valueOf(size)));
        }
        examPageMapper.insert(examPageDO);
        List<ExamQuestionRelationshipDO> examQuestionRelationshipDOList = new ArrayList<>();
        int sortNum = 1;
        for (ExamQuestionDO item : examQuestionDOList) {
            ExamQuestionRelationshipDO examQuestionRelationshipDO = new ExamQuestionRelationshipDO();
            examQuestionRelationshipDO.setId(IdUtil.getSnowflake().nextId());
            examQuestionRelationshipDO.setExamId(examId);
            examQuestionRelationshipDO.setQuestionId(item.getId());
            examQuestionRelationshipDO.setSortNum(sortNum);
            examQuestionRelationshipDOList.add(examQuestionRelationshipDO);
        }
        examQuestionRelationshipMapper.insert(examQuestionRelationshipDOList);

        Long userExamId = addUserExamLog(examBankId, examId, userId, examPageDO.getExamType());
        return userExamId;
    }

    public Long addUserExamLog(Long examBankId, Long examId, Long userId, Integer examType) {
        UserExamLogDO userExamLogDO = new UserExamLogDO();
        userExamLogDO.setId(IdUtil.getSnowflake().nextId());
        userExamLogDO.setExamBankId(examBankId);
        userExamLogDO.setExamId(examId);
        userExamLogDO.setUserId(userId);
        userExamLogDO.setBeginTime(System.currentTimeMillis());
        userExamLogDO.setEndTime(0L);
        userExamLogDO.setCostTime(0L);
        userExamLogDO.setIsDel(0);
        userExamLogDO.setScore(BigDecimal.ZERO);
        userExamLogDO.setExtraInfo("");
        userExamLogDO.setExamStatus(ExamStatus.DOING.getCode());
        userExamLogDO.setRightNum(0);
        userExamLogDO.setWrongNum(0);
        userExamLogDO.setExamType(examType);
        userExamLogDO.setCreateTime(System.currentTimeMillis());
        userExamLogMapper.insert(userExamLogDO);
        return userExamLogDO.getId();
    }


    public void addUserQuestionFlagDO(Long examBankId, Long menuId, Long userId) {
        UserQuestionFlagDO userQuestionFlagDO = new UserQuestionFlagDO();
        userQuestionFlagDO.setId(IdUtil.getSnowflakeNextId());
        userQuestionFlagDO.setUserId(userId);
        userQuestionFlagDO.setExamBankId(examBankId);
        userQuestionFlagDO.setMenuId(menuId);
        userQuestionFlagDO.setCreateTime(System.currentTimeMillis());
        userQuestionFlagMapper.insert(userQuestionFlagDO);
    }

    /**
     * 封装问题信息, 材料自己外部处理
     *
     * @param examQuestionDOList
     * @param examBankId
     * @return
     */
    List<ExamQuestionVO> warpExamQuestionVoList(List<ExamQuestionDO> examQuestionDOList, Long examBankId, Long userId) {
        if (CollectionUtils.isEmpty(examQuestionDOList)) {
            return Collections.EMPTY_LIST;
        }
        List<ExamQuestionVO> res =
                new ArrayList<>(examQuestionDOList.stream().map(examQuestionConverter::toView).toList());
        List<Long> questionIds = examQuestionDOList.stream().map(ExamQuestionDO::getId).toList();
        Map<Long, List<TagVO>> tagsByQuestionIds = getTagsByQuestionIds(questionIds, examBankId);
        Map<Long, String> userNotes = null;
        Map<Long, Integer> userCollectMap = null;
        if (userId > 0) {
            userNotes = getUserQuestionNote(questionIds, userId);
            userCollectMap = getUserCollectMap(questionIds, userId, examBankId);
        }
        for (ExamQuestionVO item : res) {
            item.setQuestionExtraInfoVO(JSON.parseObject(item.getExtraInfo(), QuestionExtraInfoVO.class));
            item.setTags(tagsByQuestionIds.getOrDefault(item.getId(), new ArrayList<>()));
            if (userId > 0 && userNotes != null) {
                item.setNote(userNotes.getOrDefault(item.getId(), ""));
            }
            if (userId > 0 && userCollectMap != null) {
                item.setIsCollect(userCollectMap.getOrDefault(item.getId(), 0) > 0);
            }
        }
        return res;
    }


    public Map<Long, List<TagVO>> getTagsByQuestionIds(List<Long> questionIds, Long examBankId) {
        List<QuestionTagDO> questionTagDOList = questionTagMapper.selectByQuestionIds(questionIds, examBankId);
        if (CollectionUtils.isNotEmpty(questionTagDOList)) {
            Set<Long> tagIds = new HashSet<>();
            questionTagDOList.forEach(questionTagDO -> tagIds.add(questionTagDO.getTagId()));
            if (CollectionUtils.isNotEmpty(tagIds)) {
                List<TagDO> tagDOList = tagMapper.selectByIds(tagIds);
                List<TagVO> tagVOList = tagDOList.stream().map(tagConverter::toView).toList();
                Map<Long, TagVO> tagVOMap = tagVOList.stream().collect(
                        HashMap::new,
                        (map, tagVO) -> map.put(tagVO.getId(), tagVO),
                        Map::putAll
                );
                Map<Long, List<TagVO>> res = new HashMap<>();
                questionTagDOList.forEach(questionTagDO -> {
                    List<TagVO> tmp = res.getOrDefault(questionTagDO.getQuestionId(), new ArrayList<>());
                    tmp.add(tagVOMap.get(questionTagDO.getTagId()));
                    res.put(questionTagDO.getQuestionId(), tmp);
                });
                return res;
            }
        }
        return new HashMap<>();
    }


    public boolean checkAnswer(String answer, ExamQuestionDO questionDO) {
        if (questionDO.getQuestionType() == QuestionTypeEnum.SINGLE_CHOICE.getCode() || questionDO.getQuestionType() == QuestionTypeEnum.MULTIPLE_CHOICE.getCode()) {
            if (questionDO.getAnswer().equals(answer)) {
                return true;
            }
            return false;
        } else {
            throw new RuntimeException("不支持的题型");
        }
    }

    /**
     * 获取收藏列表
     *
     * @param qry
     * @return
     */
    public PagedQuestionData<UserExamCollectQuestionVO> getUserCollectList(UserCollectQry qry) {
        int count = userCollectMapper.getUserCollectCount(qry);
        if (count > 0) {
            List<UserCollectDO> userCollectList = userCollectMapper.getUserCollectList(qry);
            List<Long> questionIds = new ArrayList<>();
            userCollectList.forEach(userCollectDO -> questionIds.add(userCollectDO.getQuestionId()));
            List<ExamQuestionVO> examQuestionList = getExamQuestionListByIds(questionIds,
                    qry.getExamBankId(), qry.getUserId());
            List<Long> materialsIds =
                    examQuestionList.stream().map(ExamQuestionVO::getMaterialsId).filter(x -> x > 0).toList();
            List<ExamQuestionMaterialsVO> materialsList = getExamQuestionMaterialsList(materialsIds);

            Map<Long, Long> collectQuestionMap =
                    userCollectList.stream().collect(Collectors.toMap(UserCollectDO::getQuestionId,
                            UserCollectDO::getId));
            List<UserExamCollectQuestionVO> res = new ArrayList<>();
            for (ExamQuestionVO examQuestionVO : examQuestionList) {
                UserExamCollectQuestionVO item = examQuestionConverter.toCollectView(examQuestionVO);
                item.setUserExamCollectId(collectQuestionMap.get(item.getId()));
                res.add(item);
            }
            return PagedQuestionData.of(qry, count, res, materialsList);
        } else {
            return PagedQuestionData.of(qry, 0, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
        }
    }

    public PagedQuestionData<UserExamWrongQuestionVO> getUserWrongList(UserCollectQry qry) {
        int count = userWrongMapper.getUserWrongCount(qry);
        if (count > 0) {
            List<Long> questionIds = new ArrayList<>();
            List<UserWrongDO> userWrongList = userWrongMapper.getUserWrongList(qry);
            userWrongList.forEach(userWrongDO -> questionIds.add(userWrongDO.getQuestionId()));
            List<ExamQuestionVO> examQuestionList = getExamQuestionListByIds(questionIds,
                    qry.getExamBankId(), qry.getUserId());
            List<Long> materialsIds =
                    examQuestionList.stream().map(ExamQuestionVO::getMaterialsId).filter(x -> x > 0).toList();
            List<ExamQuestionMaterialsVO> materialsList = getExamQuestionMaterialsList(materialsIds);
            Map<Long, Long> collectQuestionMap =
                    userWrongList.stream().collect(Collectors.toMap(UserWrongDO::getQuestionId,
                            UserWrongDO::getId));
            List<UserExamWrongQuestionVO> res = new ArrayList<>();
            for (ExamQuestionVO examQuestionVO : examQuestionList) {
                UserExamWrongQuestionVO item = examQuestionConverter.toWrongView(examQuestionVO);
                item.setUserExamWrongId(collectQuestionMap.get(item.getId()));
                res.add(item);
            }
            return PagedQuestionData.of(qry, count, res, materialsList);
        } else {
            return PagedQuestionData.of(qry, 0, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
        }
    }

    public List<ExamQuestionMaterialsVO> getExamQuestionMaterialsList(List<Long> materialsIds) {
        if (CollectionUtils.isEmpty(materialsIds)) {
            return Collections.EMPTY_LIST;
        }
        return examQuestionMaterialsMapper.selectByIds(materialsIds).stream().map(examQuestionMaterialsConverter::toView).toList();
    }

    public boolean addUserWrongQuestion(Long examBankId, Long userId, List<ExamQuestionDO> questionList) {
        // 这里逻辑有问题,需要处理下,之前是软删除
        // 首先更新错误次数
        List<Long> questionIds = new ArrayList<>(questionList.stream().map(ExamQuestionDO::getId).toList());
        Long now = System.currentTimeMillis();
        int res = userWrongMapper.updateWrongTimesByQuestionIds(userId, examBankId, questionIds, now);
        // 找出所有已经存在的, 返回结果>0,说明有更新
        if (res > 0) {
            List<Long> deletedIds = userWrongMapper.getUserWrongDeletedQuestionIds(userId, examBankId, questionIds);
            if (CollectionUtils.isNotEmpty(deletedIds)) {
                // 将已删除的更新为0
                userWrongMapper.refuseDelUserWrong(deletedIds, now);
            }
            List<Long> existQuestionIds = userWrongMapper.getExistUserWrongQuestionIds(userId, examBankId, questionIds);
            // 将这些都移除,剩余的就是需要待添加的
            questionIds.removeAll(existQuestionIds);
        }
        // 剩余的如果还存在的话
        if (CollectionUtils.isNotEmpty(questionIds)) {
            Set<Long> menuIds = questionList.stream().map(ExamQuestionDO::getMenuId).collect(Collectors.toSet());
            Map<Long, CardMenuDO> menuDOMap = commonService.getCardMenuDOMapByIds(menuIds);
            Map<Long, ExamQuestionDO> questionMap =
                    questionList.stream().collect(Collectors.toMap(ExamQuestionDO::getId, v -> v));
            List<UserWrongDO> userWrongDOList = new ArrayList<>();
            for (Long questionId : questionIds) {
                ExamQuestionDO question = questionMap.get(questionId);
                CardMenuDO menuDO = menuDOMap.get(question.getMenuId());
                Long topMenuId = commonService.getTopMenuIdByPath(menuDO.getPath());
                UserWrongDO userWrongDO = new UserWrongDO();
                userWrongDO.setId(IdUtil.getSnowflakeNextId());
                userWrongDO.setExamBankId(examBankId);
                userWrongDO.setQuestionId(questionId);
                userWrongDO.setUserId(userId);
                userWrongDO.setIsDel(0);
                userWrongDO.setWrongTimes(1);
                userWrongDO.setCreateTime(now);
                userWrongDO.setUpdateTime(now);
                userWrongDO.setIsReviewed(0);
                userWrongDO.setTopMenuId(topMenuId);
                userWrongDO.setMenuId(question.getMenuId());
                userWrongDOList.add(userWrongDO);
            }
            userWrongMapper.insert(userWrongDOList);
        }
        return true;
    }

    public boolean deleteUserWrong(Long userId, Long examBankId, Long questionId) {
        return userWrongMapper.deleteUserWrong(userId, examBankId, questionId) > 0;
    }


    public Map<Long, String> getUserQuestionNote(Collection<Long> questionIds, Long userId) {
        List<UserQuestionNoteDO> userQuestionNoteDOList = userQuestionNoteMapper.selectByQuestionIds(questionIds,
                userId);
        return userQuestionNoteDOList.stream().collect(Collectors.toMap(UserQuestionNoteDO::getQuestionId,
                UserQuestionNoteDO::getNote));
    }

    private Map<Long, Integer> getUserCollectMap(List<Long> questionIds, Long userId, Long examBankId) {
        List<StatisticDO> userCollectStatisticDOList =
                userCollectMapper.getUserCollectStatistic(questionIds, userId, examBankId);
        return userCollectStatisticDOList.stream().collect(Collectors.toMap(StatisticDO::getId, StatisticDO::getCnt));
    }


    public boolean addUserQuestionNote(Long userId, Long questionId, String note) {
        UserQuestionNoteDO userQuestionNoteDO = new UserQuestionNoteDO();
        userQuestionNoteDO.setId(IdUtil.getSnowflakeNextId());
        userQuestionNoteDO.setUserId(userId);
        userQuestionNoteDO.setQuestionId(questionId);
        userQuestionNoteDO.setNote(note);
        userQuestionNoteDO.setCreateTime(System.currentTimeMillis());
        return userQuestionNoteMapper.insert(userQuestionNoteDO) > 0;
    }

    public boolean addOrUpdateUserQuestionNote(Long userId, Long questionId, String note) {
        UserQuestionNoteDO userQuestionNoteDO = userQuestionNoteMapper.getItemByQuestionId(userId, questionId);
        if (userQuestionNoteDO == null) {
            return addUserQuestionNote(userId, questionId, note);
        }
        userQuestionNoteDO.setNote(note);
        return userQuestionNoteMapper.updateById(userQuestionNoteDO) > 0;
    }

    public void reviewUserWrongQuestion(ReviewUserWrongQuestionForm form) {
        UserWrongDO userWrongDO = userWrongMapper.selectById(form.getId());
        if (userWrongDO == null) {
            return;
        }
        userWrongDO.setIsReviewed(1);
        userWrongDO.setUpdateTime(System.currentTimeMillis());
        if (!form.isResult()) {
            userWrongDO.setWrongTimes(userWrongDO.getWrongTimes() + 1);
        }
        userWrongMapper.updateById(userWrongDO);
    }

    public PagedData<UserExamLogVO> getUserExamLogList(ExamLogQry qry) {
        List<UserExamLogDO> userExamLogDOList = userExamLogMapper.selectByQry(qry);
        int count = userExamLogMapper.selectCountByQry(qry);
        List<UserExamLogVO> res = userExamLogDOList.stream().map(userExamLogConverter::toView).toList();
        if (CollectionUtils.isEmpty(userExamLogDOList)) {
            return PagedData.of(qry, count, Collections.EMPTY_LIST);
        }
        List<Long> examIds = res.stream().map(UserExamLogVO::getExamId).toList();
        List<ExamPageDO> examMap = examPageMapper.selectByIds(examIds);
        Map<Long, ExamPageDO> examPageDOMap = examMap.stream().collect(Collectors.toMap(ExamPageDO::getId, v -> v));
        res.forEach(v -> {
            ExamPageDO item = examPageDOMap.get(v.getExamId());
            v.setExamName(item.getName());
            v.setExamType(item.getExamType());
            v.setHardScore(item.getHardScore());
        });

        return PagedData.of(qry, count, res);
    }

    public List<ExamQuestionVO> getQuestionListByExamId(Long examId, Long userId, Long examBankId) {
        List<Long> questionIds = examQuestionRelationshipMapper.getQuestionIdsByExamId(examId);
        List<ExamQuestionVO> res = getExamQuestionListByIds(questionIds, examBankId, userId);
        // 把res通过questionIds顺序排序
        res.sort(Comparator.comparingInt(o -> questionIds.indexOf(o.getId())));
        return res;
    }

    public List<ExamQuestionDO> getExamQuestionListByExamId(Long examId) {
        return examQuestionMapper.selectByExamId(examId);
    }

    public Map<Long, ExamQuestionDO> getExamQuestionMapByIds(List<Long> questionIds) {
        List<ExamQuestionDO> examQuestionDOList = examQuestionMapper.selectByIds(questionIds);
        if (CollectionUtils.isEmpty(examQuestionDOList)) {
            return Collections.EMPTY_MAP;
        }
        return examQuestionDOList.stream().collect(Collectors.toMap(ExamQuestionDO::getId, v -> v));
    }

    public void addUserQuestionLogList(List<UserQuestionLogDO> questionLogDOList) {
        userQuestionLogMapper.insert(questionLogDOList);
    }

    public List<UserQuestionVO> getUserQuestionByLogId(Long logId) {
        UserExamLogDO userExamLogDO = userExamLogMapper.selectById(logId);
        if (userExamLogDO == null) {
            throw new BizException(new CustomerError("500", "记录不存在"));
        }
        Long examId = userExamLogDO.getExamId();
        List<UserQuestionLogDO> userQuestionLogDOList = userQuestionLogMapper.selectByLogId(logId);
        Map<Long, UserQuestionLogDO> userQuestionLogDOMap =
                userQuestionLogDOList.stream().collect(Collectors.toMap(UserQuestionLogDO::getQuestionId, v -> v));
        List<ExamQuestionVO> questionList = getQuestionListByExamId(examId, userExamLogDO.getUserId(),
                userExamLogDO.getExamBankId());
        List<UserQuestionVO> res = new ArrayList<>();
        for (ExamQuestionVO item : questionList) {
            UserQuestionVO userQuestionVO = examQuestionConverter.toUserQuestionVO(item);
            UserQuestionLogDO userQuestionLogDO = userQuestionLogDOMap.get(item.getId());
            if (userQuestionLogDO != null) {
                userQuestionVO.setUserAnswer(userQuestionLogDO.getAnswer());
                userQuestionVO.setUserScore(userQuestionLogDO.getScore());
                userQuestionVO.setUseTime(userQuestionLogDO.getUseTime());
                userQuestionVO.setQuestionLogId(userQuestionLogDO.getId());
            } else {
                userQuestionVO.setUserAnswer("");
                userQuestionVO.setUserScore(BigDecimal.ZERO);
                userQuestionVO.setUseTime(0L);
                userQuestionVO.setQuestionLogId(null);
            }
            res.add(userQuestionVO);
        }
        return res;
    }

    public boolean reportQuestion(ReportQuestionForm form) {
        ReportQuestionDO reportQuestionDO = new ReportQuestionDO();
        reportQuestionDO.setId(IdUtil.getSnowflakeNextId());
        reportQuestionDO.setUserId(form.getUserId());
        reportQuestionDO.setQuestionId(form.getQuestionId());
        reportQuestionDO.setContext(form.getContext());
        reportQuestionDO.setCreateTime(System.currentTimeMillis());
        reportQuestionDO.setIsHandle(0);
        return reportQuestionMapper.insert(reportQuestionDO) > 0;
    }
}
